package util;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class JDBCUtils {
    static Connection connection;

    static {
        try {
            InputStream is = JDBCUtils.class.getResourceAsStream("/db.properties");
            Properties ps = new Properties();
            ps.load(is);

            String driverClassName = ps.getProperty("driverClassName");
            String url = ps.getProperty("url");
            String username = ps.getProperty("username");
            String password = ps.getProperty("password");

            // 加载数据库驱动
            Class.forName(driverClassName);

            // 创建连接  把 局部变量提成成员变量 ctrl + alt + f
            connection = DriverManager.getConnection(url, username, password);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {
        return connection;
    }

    public  static void close () {
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


    // 增 删 改
    public static int executeUpdate(String sql, Object... objs) {
        int flag = 0;
        try {
            PreparedStatement ps = connection.prepareStatement(sql);
            if (null != objs) {
                // 给 sql 里面的 ? 赋值
                for (int i = 0; i < objs.length; i++) {
                    ps.setObject(i+1, objs[i]);
                }
                flag = ps.executeUpdate();
                return flag;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    // 查询一条数据
    public static <T> T getObject(String sql, Class<T> clazz, Object... params) {
        try {
            PreparedStatement ps = connection.prepareStatement(sql);
            if (null != params) {
                // 给 sql 里面的 ? 赋值
                for (int i = 0; i < params.length ; i++ ) {
                    ps.setObject(i+1, params[i]);
                }
                // 执行查询
                ResultSet rs = ps.executeQuery();
                // 检索此 ResultSet对象的列的数量，类型和属性
                ResultSetMetaData rsd = rs.getMetaData();
                // 获取列的总数
                int columnCount = rsd.getColumnCount();
                // 通过反射创建传递类的对象
                T t = clazz.newInstance();
                while (rs.next()) {


                    for (int i = 1;i <= columnCount;i++ ) {
                        // 获取列名
                        String columnName = rsd.getColumnName(i);
                        // 根据列名获取数据库的数据
                        Object object = rs.getObject(columnName);
                        // 根据列名获取实体类的属性
                        Field field = clazz.getDeclaredField(columnName);
                        // 取消 Java 语言权限检查
                        field.setAccessible(true);
                        // 给 t 设置数据库传递的值
                        field.set(t, object);
                    }

                }
                return t;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    // 分页查询
    public static  <T> List<T> findByPage(String sql, Class<T> clazz, int pageNow,int pageSize) {
        try {
            PreparedStatement ps = connection.prepareStatement(sql);
//            if (null != params) {
                // 给 sql 里面的 ? 赋值
//                for (int i = 0; i < params.length ; i++ ) {
//                    ps.setObject(i+1, params[i]);
//                }
                ps.setInt(1,(pageNow-1)*pageSize);
                ps.setInt(2,pageSize);
                // 执行查询
                ResultSet rs = ps.executeQuery();
                // 检索此 ResultSet对象的列的数量，类型和属性
                ResultSetMetaData rsd = rs.getMetaData();
                // 获取列的总数
                int columnCount = rsd.getColumnCount();
                // 存放数据
                List<T> list = new ArrayList<T>();

                while (rs.next()) {
                    // 通过反射创建传递类的对象
                    T t = clazz.newInstance();

                    for (int i = 1;i <= columnCount;i++ ) {
                        // 获取列名
                        String columnName = rsd.getColumnName(i);
                        // 根据列名获取数据库的数据
                        Object object = rs.getObject(columnName);
                        // 根据列名获取实体类的属性
                        Field field = clazz.getDeclaredField(columnName);
                        // 取消 Java 语言权限检查
                        field.setAccessible(true);
                        // 给 t 设置数据库传递的值
                        field.set(t, object);
                    }

                    list.add(t);
                }
                return list;
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 查询多条数据
    public static <T> List<T> getObjects(String sql, Class<T> clazz, Object... params) {
        try {
            PreparedStatement ps = connection.prepareStatement(sql);
            if (null != params) {
                // 给 sql 里面的 ? 赋值
                for (int i = 0; i < params.length ; i++ ) {
                    ps.setObject(i+1, params[i]);
                }
                // 执行查询
                ResultSet rs = ps.executeQuery();
                // 检索此 ResultSet对象的列的数量，类型和属性
                ResultSetMetaData rsd = rs.getMetaData();
                // 获取列的总数
                int columnCount = rsd.getColumnCount();
                // 存放数据
                List<T> list = new ArrayList<T>();

                while (rs.next()) {
                    // 通过反射创建传递类的对象
                    T t = clazz.newInstance();

                    for (int i = 1;i <= columnCount;i++ ) {
                        // 获取列名
                        String columnName = rsd.getColumnName(i);
                        // 根据列名获取数据库的数据
                        Object object = rs.getObject(columnName);
                        // 根据列名获取实体类的属性
                        Field field = clazz.getDeclaredField(columnName);
                        // 取消 Java 语言权限检查
                        field.setAccessible(true);
                        // 给 t 设置数据库传递的值
                        field.set(t, object);
                    }

                    list.add(t);
                }
                return list;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 查询总记录数
    public static int getCount(String tableName) {
        try {
            PreparedStatement ps = connection.prepareStatement("select count(*) from " + tableName);
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                return rs.getInt("count(*)");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }
}
